package com.bestcem.xm.member.handler.export.easyExcel;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.style.AbstractCellStyleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;

import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import static com.bestcem.xm.member.constant.Constants.*;

/**
 * 单元格样式
 *
 * @author yf.wang <yf.wang@idiaoyan.com>
 * @version V1.0
 * @date 2021/8/2
 */
@Slf4j
public class ExcelWriteHandler extends AbstractCellStyleStrategy implements CellWriteHandler, Closeable {

    private final ThreadLocal<CellStyle> THREAD_LOCAL_STYLE = new ThreadLocal<>();

    /**
     * 表头类型映射
     */
    private Map<String, String> headerTypeMap;

    public void setHeaderTypeMap(Map<String, String> headerTypeMap) {
        this.headerTypeMap = headerTypeMap;
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {

    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {

    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData<?> cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        CellStyle cellStyle = this.createCellStyle(writeSheetHolder.getSheet().getWorkbook());
        // 获取表头数据
        String headerName = head.getHeadNameList().get(0);
        if (!isHead) {
            // 数字 日期 类型 居右 其他类型的居左  和 excel的默认保持一致
            switch (headerTypeMap.getOrDefault(headerName, EXCEL_TYPE_STR)) {
                case EXCEL_TYPE_NUMBER:
                case EXCEL_TYPE_DATE:
                    cellStyle.setAlignment(HorizontalAlignment.RIGHT);
                    cell.setCellStyle(cellStyle);
                    break;
                default:
                    cellStyle.setAlignment(HorizontalAlignment.LEFT);
                    cell.setCellStyle(cellStyle);
            }
        }
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder,
                                 WriteTableHolder writeTableHolder,
                                 List<WriteCellData<?>> list,
                                 Cell cell,
                                 Head head,
                                 Integer relativeRowIndex,
                                 Boolean isHead) {

    }


    @Override
    protected void setHeadCellStyle(Cell cell, Head head, Integer integer) {

    }

    @Override
    protected void setContentCellStyle(Cell cell, Head head, Integer integer) {

    }

    /**
     * 清理本地cell style缓存
     * @throws IOException
     */
    @Override
    public void close() throws IOException {
        THREAD_LOCAL_STYLE.remove();
        if(log.isInfoEnabled()){
            log.info("已清理 CellStyle");
        }
    }

    /**
     * 从缓存获取 cell style
     * 目前一次导出只有一种cell style
     * @param workbook workbook
     * @return cell style
     */
    private CellStyle createCellStyle(Workbook workbook){
        CellStyle cellStyle = THREAD_LOCAL_STYLE.get();
        if(cellStyle == null){
            cellStyle = workbook.createCellStyle();
            THREAD_LOCAL_STYLE.set(cellStyle);
        }
        return cellStyle;
    }
}
